#include "all.h"

#if 0
		TITLE	RECORDS - Copyright (c) SLR Systems 1994

		INCLUDE	MACROS
		INCLUDE	IO_STRUC

		PUBLIC	GET_RECORD,CHECK_CHECKSUM,GET_FIRST_RECORD

if	fg_rom
		PUBLIC	CHECKSUM
endif

		.DATA

		EXTERNDEF	TEMP_RECORD:BYTE

		EXTERNDEF	OBJ_DEVICE:DWORD,RECORD_LENGTH:DWORD,END_OF_RECORD:DWORD,BUFFER_OFFSET:DWORD,RECORD_TYPE:DWORD


		.CODE	PASS1_TEXT

		EXTERNDEF	_err_abort:proc,ERR_RET:PROC,WARN_RET:PROC

		EXTERNDEF	BAD_CHKSUM_ERR:ABS,UNEXP_EOF_ERR:ABS,REC_TOO_LONG_ERR:ABS,INVALID_OBJ_ERR:ABS

GET_FIRST_RECORD	PROC
		;
		;RETURN LENGTH IN BX, REST OF RECORD IN DS:SI
		;
		MOV	EBX,OBJ_DEVICE
		ASSUME	EBX:PTR MYI_STRUCT

		MOV	DL,-1
		XOR	EAX,EAX
		SETT	REC_TYPE_VALID,DL
		MOV	EDX,[EBX].MYI_COUNT
		MOV	ESI,[EBX].MYI_PTRA
		SUB	EDX,3
		JC	RPTR_HELP_AF
		MOV	[EBX].MYI_COUNT,EDX
		; Bugzilla 3372
		; Seg fault with ESI = 0x636F9050
		MOV	AL,[ESI]
		MOV	BUFFER_OFFSET,ESI
		CMP	AL,80H
		JZ	GR_CONTINUE1
		CMP	AL,6EH
		JZ	GR_CONTINUE1
		BITT	LIB_OR_NOT		;CANNOT BE F0 IF ALREADY IN A
		JNZ	L8$			;LIB
		CMP	AL,0F0H
		JNZ	L8$
GR_CONTINUE1:
		JMP	GR_CONTINUE
L8$:
		SETT	REC_TYPE_VALID
		MOV	AL,INVALID_OBJ_ERR
		push	EAX
		call	_err_abort

RPTR_HELP_AF:
		MOV	AL,3
		RESS	REC_TYPE_VALID,AH
		CALL	RPTR_HELP
		MOV	AL,[ESI]
		MOV	BUFFER_OFFSET,ESI
		MOV	BPTR RECORD_TYPE,AL		;STORE TYPE
		CMP	AL,80H
		JZ	GF_CONT
		CMP	AL,6EH
		JZ	GF_CONT
		BITT	LIB_OR_NOT
		JNZ	L8$
		CMP	AL,0F0H
		JNZ	L8$
GF_CONT:
		XOR	EAX,EAX
		MOV	DL,-1
		MOV	AX,1[ESI]
		ADD	ESI,3
		SETT	REC_TYPE_VALID,DL
		CMP	EAX,MAX_RECORD_LEN+1
		JNC	REC_TOO_LONG
		MOV	ESI,[EBX].MYI_PTRA
		JMP	RPTR_HELP_A_RET

GET_FIRST_RECORD	ENDP


GET_RECORD	PROC
		;
		;REST OF RECORD IN ESI
		;
		MOV	EBX,OBJ_DEVICE
		MOV	DL,-1

		XOR	EAX,EAX
		SETT	REC_TYPE_VALID,DL

		MOV	EDX,[EBX].MYI_COUNT
		MOV	ESI,[EBX].MYI_PTRA

		SUB	EDX,3
		JC	RPTR_HELP_A

		MOV	[EBX].MYI_COUNT,EDX
		MOV	AL,[ESI]

		MOV	BUFFER_OFFSET,ESI
GR_CONTINUE::
		MOV	AH,2[ESI]

		MOV	BPTR RECORD_TYPE,AL	;STORE TYPE
		MOV	AL,1[ESI]

		ADD	ESI,3
RPTR_HELP_A_RET::
		MOV	RECORD_LENGTH,EAX	;LENGTH

		CMP	EAX,MAX_RECORD_LEN+1
		JNC	REC_TOO_LONG
RPTR_A1:
		MOV	EDX,[EBX].MYI_COUNT
		LEA	EDI,[EAX+ESI]

		SUB	EDX,EAX
		MOV	[EBX].MYI_PTRA,EDI

		DEC	EDI
		JC	RPTR_HELP_B

		MOV	[EBX].MYI_COUNT,EDX
		MOV	END_OF_RECORD,EDI

		RET

RPTR_HELP_A:
		MOV	AL,3
		RESS	REC_TYPE_VALID,AH
		CALL	RPTR_HELP
		MOV	AL,[ESI]
		MOV	BUFFER_OFFSET,ESI
		MOV	BPTR RECORD_TYPE,AL		;STORE TYPE
		XOR	EAX,EAX
		MOV	DL,-1
		MOV	AX,1[ESI]
		MOV	ESI,[EBX].MYI_PTRA
		SETT	REC_TYPE_VALID,DL
		JMP	RPTR_HELP_A_RET

REC_TOO_LONG::
		DEC	ESI
		MOV	AL,REC_TOO_LONG_ERR
		MOV	END_OF_RECORD,ESI
		push	EAX
		call	_err_abort

RPTR_HELP_B	LABEL	PROC

		MOV	[EBX].MYI_PTRA,ESI	;RESTORE PTR

RPTR_HELP	LABEL	PROC
		;
		;MOVE WHAT YOU CAN TO TEMP_RECORD
		;
		LEA	ECX,[EDX+EAX]
		MOV	EDI,OFF TEMP_RECORD
		PUSH	EAX		;BYTES TO READ
		SUB	EAX,ECX		;NUMBER TO MOVE AFTER THE FACT
		TEST	ECX,ECX
		PUSH	EDI
		JZ	RH_1
		MOV	ESI,[EBX].MYI_PTRA
		OPTI_MOVSB
RH_1:
		MOV	ESI,EAX
		MOV	EAX,EBX

		push	EAX
		CALL	[EBX].MYI_FILLBUF
		add	ESP,4

		POP	EDX
		MOV	ECX,ESI
		SUB	[EBX].MYI_COUNT,ESI
		MOV	ESI,[EBX].MYI_PTRA
		JC	UNEXP_EOF
		POP	EAX
		OPTI_MOVSB
		MOV	[EBX].MYI_PTRA,ESI
		LEA	ECX,[EDX+EAX-1]
		MOV	ESI,EDX
		MOV	END_OF_RECORD,ECX
		RET

UNEXP_EOF:
		MOV	AL,UNEXP_EOF_ERR
		push	EAX
		call	_err_abort

GET_RECORD	ENDP
#endif

void _print_obj_device()
{
    MYI_STRUCT *ms = OBJ_DEVICE;
    printf("ms = %p\n", ms);
    printf("MYI_COUNT  = %x\n", ms->MYI_COUNT);
    printf("MYI_HANDLE = %p\n", ms->MYI_HANDLE);
    printf("MYI_PTRA   = %p\n", ms->MYI_PTRA);
    printf("MYI_BLOCK  = %p\n", ms->MYI_BLOCK);
    printf("MYI_FILE_LENGTH = %x\n", ms->MYI_FILE_LENGTH);
    printf("MYI_BYTE_OFFSET = %x\n", ms->MYI_BYTE_OFFSET);
    printf("MYI_PHYS_ADDR = %x\n", ms->MYI_PHYS_ADDR);
    printf("MYI_FILLBUF   = %x\n", ms->MYI_FILLBUF);
    printf("MYI_FILE_LIST_GINDEX = %p\n", ms->MYI_FILE_LIST_GINDEX);
    printf("MYI_BUSY = %x\n", ms->MYI_BUSY);
    printf("MYI_TIME = %x\n", ms->MYI_TIME);
    printf("MYI_DATE = %x\n", ms->MYI_DATE);
    printf("MYI_CURRENT_TYPE = %x\n", ms->MYI_CURRENT_TYPE);
    printf("MYI_BUFCNT = %x\n", ms->MYI_BUFCNT);
    printf("reserved   = %x\n", ms->reserved);
}


void _check_checksum(unsigned char *ESI)
{
    // RECALC. THE CHECKSUM FROM THE DATA AND COMPARE TO THE
    // CHECKSUM READ IN FROM BUFFER
    unsigned ECX = RECORD_LENGTH;
    if (!ESI[ECX - 1])	// don't bother if not there
	return;
    unsigned char DL = RECORD_TYPE;	// also part of records check sum	
    while (1)
    {
	switch (ECX)
	{
	    case 0:
		break;
	    case 1:
		DL += ESI[0];
		break;
	    case 2:
		DL += ESI[0] + ESI[1];
		break;
	    case 3:
		DL += ESI[0] + ESI[1] + ESI[2];
		break;
	    default:
		do
		{   DL += ESI[0] + ESI[1] + ESI[2] + ESI[3];
		    ESI += 4;
		    ECX -= 4;
		} while (ECX >= 4);
		continue;
	}
	break;
    }

    DL += RECORD_LENGTH & 0xFF;
    DL += (RECORD_LENGTH >> 8) & 0xFF;

    if (DL)
	_warn_ret(BAD_CHKSUM_ERR);
}
